package com.wang.jmonkey.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.jmonkey.common.exception.ServiceException;
import com.wang.jmonkey.common.utils.TreeUtil;
import com.wang.jmonkey.modules.system.mapper.SystemDutyMapper;
import com.wang.jmonkey.modules.system.model.dto.SystemDutyTreeDto;
import com.wang.jmonkey.modules.system.model.entity.SystemDutyEntity;
import com.wang.jmonkey.modules.system.model.enums.SystemAclPrincipalTypeEnum;
import com.wang.jmonkey.modules.system.model.enums.SystemDaclPrincipalTypeEnum;
import com.wang.jmonkey.modules.system.service.SystemAclService;
import com.wang.jmonkey.modules.system.service.SystemDaclService;
import com.wang.jmonkey.modules.system.service.SystemDutyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;

/**
 * 职务信息(SystemDuty)表服务实现类
 *
 * @author HeJiawang
 * @since 2021-07-24 15:42:39
 */
@Service
public class SystemDutyServiceImpl extends ServiceImpl<SystemDutyMapper, SystemDutyEntity> implements SystemDutyService {

    /**
     * mapper
     */
    @Autowired
    private SystemDutyMapper mapper;

    @Autowired
    private SystemAclService systemAclService;

    @Autowired
    private SystemDaclService systemDaclService;

    /**
     * 获取树形结构数据
     * @return 树形结构数据集合
     */
    @Override
    public List<SystemDutyTreeDto> listTree() {
        List<SystemDutyTreeDto> result = mapper.listTree();
        return TreeUtil.build(result);
    }

    /**
     * 维护path字段信息
     * @param entity 实体信息
     */
    private void buildPath(SystemDutyEntity entity) {
        String path = StrUtil.EMPTY;

        if (ObjectUtil.isNotEmpty(entity.getParentId())) {
            SystemDutyEntity parentDept = mapper.selectById(entity.getParentId());
            if (ObjectUtil.isEmpty(parentDept)) throw new ServiceException("上级信息已不存在");

            // 维护path字段
            path = String.format(
                    "%s%s,",
                    StrUtil.isEmpty(parentDept.getPath()) ? StrUtil.EMPTY : parentDept.getPath(),
                    parentDept.getId()
            );
        }

        entity.setPath(path);
    }

    /**
     * 新增职务信息
     * @param duty 职务信息
     * @return true 新增成功
     */
    @Override
    public boolean save(SystemDutyEntity duty) {
        buildPath(duty);

        return super.save(duty);
    }

    /**
     * 修改职务信息
     * @param duty 职务信息
     * @return true 修改成功
     */
    @Override
    public boolean updateById(SystemDutyEntity duty) {
        SystemDutyEntity dept = mapper.selectById(duty.getId());
        if (ObjectUtil.isEmpty(dept)) throw new ServiceException("职务信息不存在");

        // 维护path字段值
        buildPath(duty);

        // 更新下级区域信息path字段值
        String oldPath = String.format(
                "%s%s,",
                StrUtil.isEmpty(dept.getPath()) ? StrUtil.EMPTY : dept.getPath(),
                dept.getId()
        );
        String newPath = String.format(
                "%s%s,",
                StrUtil.isEmpty(duty.getPath()) ? StrUtil.EMPTY : duty.getPath(),
                duty.getId()
        );

        return super.updateById(duty) && mapper.refreshPath(oldPath, newPath) >= 0;
    }

    /**
     * 删除职务信息
     * @param id 职务信息id
     * @return true 删除成功
     */
    @Override
    public boolean removeById(Serializable id) {
        SystemDutyEntity duty = mapper.selectById(id);
        if (ObjectUtil.isEmpty(duty)) return false;

        // 根据path删除下级区域
        String path = String.format(
                "%s%s,",
                StrUtil.isEmpty(duty.getPath()) ? StrUtil.EMPTY : duty.getPath(),
                duty.getId()
        );
        QueryWrapper<SystemDutyEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("path", path);

        List<SystemDutyEntity> dutyList = super.list(queryWrapper);
        if (CollUtil.isNotEmpty(dutyList)) {
            dutyList.forEach(dutyEntity -> {
                systemAclService.deleteByPrincipalId(dutyEntity.getId(), SystemAclPrincipalTypeEnum.DUTY);
                systemDaclService.deleteByPrincipalId(dutyEntity.getId(), SystemDaclPrincipalTypeEnum.DUTY);
            });

            super.remove(queryWrapper);
        }

        return super.removeById(id)
                &&systemAclService.deleteByPrincipalId(id, SystemAclPrincipalTypeEnum.DUTY)
                &&systemDaclService.deleteByPrincipalId(id, SystemDaclPrincipalTypeEnum.DUTY);
    }

}
